package org.boot.easyapi.file.dao;

import org.boot.easyapi.enums.db.DbEnum;
import org.boot.easyapi.file.config.FileStorageConfig;
import org.boot.easyapi.file.entity.FileInfoDO;
import org.boot.easyapi.util.jdbc.JdbcUtil;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Repository
public class FileInfoRepository {

    @Resource
    private FileStorageConfig fileStorageConfig;

    @Resource
    private JdbcTemplate jdbcTemplate;

    private final RowMapper<FileInfoDO> rowMapper = (rs, rowNum) -> {
        FileInfoDO fileInfo = new FileInfoDO();
        fileInfo.setId(rs.getLong("id"));
        fileInfo.setFileName(rs.getString("file_name"));
        fileInfo.setFilePath(rs.getString("file_path"));
        fileInfo.setFileSize(rs.getLong("file_size"));
        fileInfo.setUploadTime(rs.getTimestamp("upload_time"));
        fileInfo.setMd5(rs.getString("md5"));
        fileInfo.setStatus(rs.getInt("status"));
        fileInfo.setType(rs.getString("type"));
        fileInfo.setFileKey(rs.getString("file_key"));
        return fileInfo;
    };

    public Long save(FileInfoDO fileInfo) {

        String sql;
        if(JdbcUtil.checkDbType() == DbEnum.POSTGRESQL){
            sql = "INSERT INTO easyapi_core_file_info " +
                    "(file_name, file_path, file_size, md5, status, type, file_key) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?) " +
                    "RETURNING id";
        } else {
            sql = "INSERT INTO easyapi_core_file_info " +
                    "(file_name, file_path, file_size, md5, status, type, file_key) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?)";
        }

        KeyHolder keyHolder = new GeneratedKeyHolder();

        jdbcTemplate.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setString(1, fileInfo.getFileName());
            ps.setString(2, fileInfo.getFilePath());
            ps.setLong(3, fileInfo.getFileSize());
            ps.setString(4, fileInfo.getMd5());
            ps.setInt(5, fileInfo.getStatus());
            ps.setString(6, fileInfo.getType());
            ps.setString(7, fileInfo.getFileKey());
            return ps;
        }, keyHolder);

        // 返回主键 ID
        return keyHolder.getKey().longValue();
    }


    public List<FileInfoDO> findList(FileInfoDO fileInfoDO) {
        String sql = "SELECT * FROM easyapi_core_file_info WHERE 1=1 ";
        if (fileStorageConfig.getRootPath() != null && !fileStorageConfig.getRootPath().isEmpty()) {
            sql += " AND file_path LIKE '%" + fileStorageConfig.getRootPath() + "%'";
        }
        if (fileInfoDO != null){
            if (fileInfoDO.getFileName() != null && !fileInfoDO.getFileName().isEmpty()) {
                sql += " AND file_name LIKE '%" + fileInfoDO.getFileName() + "%'";
            }
            if (fileInfoDO.getMd5() != null && !fileInfoDO.getMd5().isEmpty()) {
                sql += " AND md5 LIKE '%" + fileInfoDO.getMd5() + "%'";
            }
            if (fileInfoDO.getType() != null && !fileInfoDO.getType().isEmpty()) {
                sql += " AND type LIKE '%" + fileInfoDO.getType() + "%'";
            }
            if (fileInfoDO.getFileKey() != null && !fileInfoDO.getFileKey().isEmpty()) {
                sql += " AND file_key LIKE '%" + fileInfoDO.getFileKey() + "%'";
            }
        }
        sql += " ORDER BY upload_time DESC";
        return jdbcTemplate.query(sql, rowMapper);
    }


    public FileInfoDO findById(Long id) {
        String sql = "SELECT * FROM easyapi_core_file_info WHERE id = ? ";
        if (fileStorageConfig.getRootPath() != null && !fileStorageConfig.getRootPath().isEmpty()) {
            sql += " AND file_path LIKE '%" + fileStorageConfig.getRootPath() + "%'";
        }
        try {
            return jdbcTemplate.queryForObject(sql, rowMapper, id);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }
    public List<FileInfoDO> findByIds(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return new ArrayList<>();
        }
        String inSql = String.join(",", Collections.nCopies(ids.size(), "?"));
        String sql = String.format("SELECT * FROM easyapi_core_file_info WHERE id IN (%s) ", inSql);
        return jdbcTemplate.query(sql, rowMapper, ids.toArray());
    }

    public int deleteById(Long id) {
        String sql = "DELETE FROM easyapi_core_file_info WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }

    public int deleteByIds(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return 0;
        }
        String inSql = String.join(",", Collections.nCopies(ids.size(), "?"));
        String sql = String.format("DELETE FROM easyapi_core_file_info WHERE id IN (%s)", inSql);
        return jdbcTemplate.update(sql, ids.toArray());
    }
}